package com.kangyi.app.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.kangyi.app.mapper.*;
import com.kangyi.app.service.UserService;
import com.kangyi.constant.MessageConstant;
import com.kangyi.constant.StatusConstant;
import com.kangyi.context.BaseContext;
import com.kangyi.dto.*;
import com.kangyi.entity.NursingHomeReview;
import com.kangyi.entity.User;
import com.kangyi.exception.AccountException;
import com.kangyi.exception.AccountNotFoundException;
import com.kangyi.exception.DataNotExistException;
import com.kangyi.exception.PasswordErrorException;
import com.kangyi.result.PageResult;
import com.kangyi.utils.AuthUtil;
import com.kangyi.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.List;

/**
 * @author Blank
 * @version 1.0
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private NursingHomeBookingMapper nursingHomeBookingMapper;

    @Autowired
    private ActivitySignupMapper activitySignupMapper;

    @Autowired
    private NursingHomeReviewMapper nursingHomeReviewMapper;

    @Autowired
    private NursingHomeReviewImageMapper nursingHomeReviewImageMapper;

    @Autowired
    private NursingHomeFavoriteMapper nursingHomeFavoriteMapper;

    @Autowired
    private NursingHomeTagMapper nursingHomeTagMapper;

    @Override
    public User login(UserLoginDTO userLoginDTO) {
        String phone = userLoginDTO.getPhone();
        String password = userLoginDTO.getPassword();

        User user = userMapper.getUser(phone);
        if (user == null) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(user.getPassword())) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }
        // 处理手机号隐藏后 6 位
        if (user.getPhone() != null && user.getPhone().length() >= 6) {
            user.setPhone(user.getPhone().substring(0, user.getPhone().length() - 6) + "******");
        }
        return user;
    }

    @Override
    public void register(UserDTO userDTO) {

        //校验账号是否已存在
        User userByPhone = userMapper.getUser(userDTO.getPhone());
        if (userByPhone != null) {
            throw new AccountException(MessageConstant.ACCOUNT_EXIST);
        }

        User user = User.builder()
                .password(DigestUtils.md5DigestAsHex(userDTO.getPassword().getBytes()))
                .phone(userDTO.getPhone())
                .status(StatusConstant.ENABLE)
                .build();

        userMapper.insert(user);
    }

    @Override
    public void resetPassword(ForgotPasswordDTO forgotPasswordDTO) {
        User user = userMapper.getUser(forgotPasswordDTO.getPhone());
        if (user == null) {
            throw new AccountException(MessageConstant.ACCOUNT_NOT_FOUND);
        }
        forgotPasswordDTO.setNewPassword(DigestUtils.md5DigestAsHex(forgotPasswordDTO.getNewPassword().getBytes()));

        userMapper.resetPassword(forgotPasswordDTO);
    }

    @Override
    public UserVO inquiryUser() {
        Integer currentId = BaseContext.getCurrentId();

        if (currentId == null) {
            throw new DataNotExistException(MessageConstant.TOKEN_IS_NOT_EXIST);
        }

        return userMapper.selectById(currentId);
    }

    @Override
    public void update(UserEditDTO userEditDto) {
        User user = User.builder()
                .id(userEditDto.getId())
                .name(userEditDto.getName())
                .headshot(userEditDto.getHeadshot()).build();
        userMapper.update(user);
    }

    @Override
    public PageResult nursingHomeAppointments(NursingHomeAppointmentsDTO nursingHomeAppointmentsDTO) {
        AuthUtil.validateUserPermission(nursingHomeAppointmentsDTO.getUserId());
        PageHelper.startPage(nursingHomeAppointmentsDTO.getPage(),nursingHomeAppointmentsDTO.getPageSize());
        Page<NursingHomeAppointmentsVO> page = nursingHomeBookingMapper.list(nursingHomeAppointmentsDTO);
        long total = page.getTotal();
        List<NursingHomeAppointmentsVO> result = page.getResult();
        return new PageResult(total,result);
    }

    @Override
    public PageResult charityRegistrations(CharityRegistrationsDTO charityRegistrationsDTO) {
        AuthUtil.validateUserPermission(charityRegistrationsDTO.getUserId());
        PageHelper.startPage(charityRegistrationsDTO.getPage(),charityRegistrationsDTO.getPageSize());
        Page<CharityRegistrationsVO> page = activitySignupMapper.charityRegistrations(charityRegistrationsDTO);
        long total = page.getTotal();
        List<CharityRegistrationsVO> result = page.getResult();
        return new PageResult(total,result);
    }

    @Override
    public PageResult reviews(UserPageDTO userPageDTO) {
        AuthUtil.validateUserPermission(userPageDTO.getUserId());
        PageHelper.startPage(userPageDTO.getPage(),userPageDTO.getPageSize());
        Page<ReviewsVO> page = nursingHomeReviewMapper.reviewsList(userPageDTO);
        long total = page.getTotal();
        List<ReviewsVO> result = page.getResult();
        for (ReviewsVO vo : result) {
            List<String> images = nursingHomeReviewImageMapper.getImages(vo.getId());
            vo.setImages(images);
        }
        return new PageResult(total,result);
    }

    @Override
    public void deleteReview(Integer reviewId) {
        NursingHomeReview nursingHomeReview = nursingHomeReviewMapper.getByReviewId(reviewId);
        AuthUtil.validateUserPermission(nursingHomeReview.getUserId());
        nursingHomeReviewImageMapper.deleteReview(reviewId);
        nursingHomeReviewMapper.deleteReview(reviewId);
    }

    @Override
    public PageResult favorites(UserPageDTO userPageDTO) {
        AuthUtil.validateUserPermission(userPageDTO.getUserId());
        PageHelper.startPage(userPageDTO.getPage(),userPageDTO.getPageSize());
        Page<FavoritesVO> page = nursingHomeFavoriteMapper.favoritesList(userPageDTO);
        long total = page.getTotal();
        List<FavoritesVO> result = page.getResult();
        for (FavoritesVO vo : result) {
            Integer reviewCount = nursingHomeReviewMapper.reviewCount(vo.getNursingHomeId());
            vo.setReviewCount(reviewCount);
            List<String> tags = nursingHomeTagMapper.getTags(vo.getNursingHomeId());
            vo.setTags(tags);
        }
        return new PageResult(total,result);
    }


}
